前言
dagger2 是解决Android或着Java中依赖注入的一个类库(DI类库)。最近看了一些开源的项目都在使用dagger2,而且有很多对其是甚是推崇,我也蠢蠢欲动。。。在学习dagger2的过程中,我遇到了一下的困惑:
- dagger2 中的Inject,Component,Module,Provides等等都是什么鬼?有什么作用
- dagger2 到底有什么魔力,让大家都推崇备至
- 如何在项目中更好的使用dagger2 ?
在具体的学习过程中,看了好多的博客,有时候感觉挺简单,就那么回事吧,但是真正使用的时候,一脸懵逼了。Component应该怎么用?Module应该放些神马?Scope怎么起到作用域控制?。。。一瞬间怀疑人生。本文将自己对dagger2的理解与大家分享一下,希望能对大家有所帮助。
摘要
Inject,Component,Module,Provides他们是什么? 怎么去理解?各自有什么作用?主要讲解抽象的概念,代码的剖析,后期实践中再说~ 下面请看黑板
小科普
Dagger2 就是通过注解实现依赖注入的一种技术手段。
进入正题
Dagger2 注入框架最重要的就是注解的使用,那么我们先来逐个分析这些东东。
@Inject注解
1 | class A { |
@Inject 注解用来标注目标类依赖的实例以以及被依赖类的构造函数。这样,目标类中依赖的实例与被依赖类的构造函数之间有了一种的联系,茫茫大海中,如何找到相互关联的两个 @Inject注解?
@Component 注解
@Component 是连接目标类依赖的实例和被依赖类构造方法的桥梁,@Component标注的类是接口或者抽象类。既然说它是桥梁,我们来分析一下,它是如何工作的。
- Component类持有目标类的实例。
- Component查找目标类中用@Inject注解标注的属性,然后查找该属性对应的用@Inject标注的构造函数。
- 初始化该属性的实例,并进行赋值。
Component 就像是一个注入器,将目标类依赖的实例注入到目标类中。
Tip:Dagger依赖注入的流程
- @Inject 标注目标类中的依赖类
- @Inject 标注被依赖类的构造函数
- 若依赖类还有依赖类,重复 step1 step2
- 调用 Component 的 injectXXX(Object) 方法开始依赖注入。(injectXXX 方法名称是官方推荐。)
@Module 注解
新坑来啦!!!项目中会使用很多的第三方类库,对于这些类库的依赖,我们没有办法去修改,不能将@Inject加入到这些类中。这可如何是好。。。
@Module 应运而生,我们可以将第三方类库封装入Module中,来对第三方库进行封装,当然@Module的功能不止封装第三方库,它的应用场景主要有以下三个:
- 接口(Interface)是没有构造方法的
- 第三方库提供的类,构造方法不能被注解
- 有些类需要灵活选择初始化配置,而不是使用单一的构造方法
Module 其实是一个简单工厂模式,Module里面的方法基本都是创建类示例的方法。
1 |
|
Module 和 Component 又是如何关联起来呢?
Component的新任务
Component 是注入器,它一段连接目标类,另一端链接被依赖类。之前说到Module类是一个提供类实例的类,所以Component的新职责就是将Module提供的被依赖类示例注入到目标类中。(Component中的modules属性可以把Module加入Component,modules可以加入多个Module)。
引入新问题,Modules 中创建的各种类实例如何注入到目标类中,如何与目标类中@Inject标注的依赖产生关联。
@Provides注解
Module 中创建类实例方法用Provides进行标注,Component 在搜索到目标类中用 @Inject 标注的属性后,Component就会去 Module 中去查找用 Provides 标注的对应的创建类实例方法,实现依赖注入。
总结
Inject,Component,Module,Provides 是dagger2中最基础最核心的知识点。
- @Inject 用来标注目标类的依赖和被依赖类的构造函数
- @Component 是一个桥梁,一端是目标类,一端是目标类所依赖的实例。负责依赖注入,同时管理 Module。
- Module 和 Provides Module是一个简单工厂模式,主要包含创建类示例的方法,这些方法用Provides来标注。
author: @ygwang